package com.linQing.waterWork.utils;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

import java.beans.PropertyEditorSupport;
import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.*;

public class DateUtils extends org.apache.commons.lang3.time.DateUtils
{
    public static final String YYYY = "yyyy";

    public static final String YYYY_MM = "yyyy-MM";

    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static final Date START = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, "1970-01-01 08:00:00");

    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    private static final String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    public static Date getNowDate()
    {
        return new Date();
    }
    public static Date getYesterdayDate() {
        // 获取当前时间的毫秒值
        long currentMillis = System.currentTimeMillis();
        // 计算昨天的日期（当前日期减去一天的毫秒数）
        long yesterdayMillis = currentMillis - 1000 * 60 * 60 * 24;
        // 使用昨天的毫秒值创建一个新的Date对象
        return new Date(yesterdayMillis);
    }

    /**
     * 获取当前年份，格式为 yyyy
     *
     * @return 当前年份的字符串表示，例如 "2024"
     */
    public static String getCurrentYear() {
        return dateTimeNow(YYYY);
    }

    public static String getDate()
    {
        return dateTimeNow(YYYY_MM_DD);
    }

    public static String getTime()
    {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    public static String dateTimeNow()
    {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static String dateTimeNow(final String format)
    {
        return parseDateToStr(format, new Date());
    }

    public static String date(final Date date)
    {
        return parseDateToStr(YYYY_MM_DD, date);
    }

    public static String dateTime(final Date date)
    {
        return parseDateToStr(YYYY_MM_DD_HH_MM_SS, date);
    }

    public static Date dateToISODate(Date date){
        //T代表后面跟着时间，Z代表UTC统一时间
        SimpleDateFormat format =
                new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        format.setCalendar(new GregorianCalendar(new SimpleTimeZone(0, "GMT")));
        String isoDate = format.format(date);
        try {
            return format.parse(isoDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date getEndTime()
    {
        Date date = new Date();
        String endTime = parseDateToStr(YYYY_MM_DD_HH_MM_SS, date);
        String subEndTime = endTime.substring(0, 13) + ":00:00";
        return dateTime(YYYY_MM_DD_HH_MM_SS, subEndTime);
    }

    public static String getEndTimeStr()
    {
        Date date = new Date();
        String endTime = parseDateToStr(YYYY_MM_DD_HH_MM_SS, date);
        return endTime.substring(0, 13) + ":00:00";

    }

    public static Date getLessTime()
    {
        Date date = new Date();
        Date lessHour = lessHour(date);
        String beginTime = parseDateToStr(YYYY_MM_DD_HH_MM_SS, lessHour);
        String subBeginTime = beginTime.substring(0, 13) + ":00:00";
        return dateTime(YYYY_MM_DD_HH_MM_SS, subBeginTime);
    }

    public static Date getLessTimeTo(Date date)
    {
        Date lessHour = lessHour(date);
        String beginTime = parseDateToStr(YYYY_MM_DD_HH_MM_SS, lessHour);
        String subBeginTime = beginTime.substring(0, 13) + ":00:00";
        return dateTime(YYYY_MM_DD_HH_MM_SS, subBeginTime);
    }

    public static Date getLessTimeToDay(Date date, int len)
    {
        Date lessDay = lessDay(date, len);
        String beginTime = parseDateToStr(YYYY_MM_DD_HH_MM_SS, lessDay);
        String subBeginTime = beginTime.substring(0, 11) + "00:00:00";
        return dateTime(YYYY_MM_DD_HH_MM_SS, subBeginTime);
    }

    public static String parseDateToStr(final String format, final Date date)
    {
        return new SimpleDateFormat(format).format(date);
    }

    public static Date dateTime(final String format, final String ts)
    {
        try
        {
            return new SimpleDateFormat(format).parse(ts);
        }
        catch (ParseException e)
        {
            throw new RuntimeException(e);
        }
    }

    public static Date formatD(String dateStr){
        return formatD(dateStr,  YYYY_MM_DD_HH_MM_SS);
    }

    public static Date formatD(String dateStr ,String format)  {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        Date ret = null ;
        try {
            ret = simpleDateFormat.parse(dateStr) ;
        } catch (ParseException e) {
        }
        return ret;
    }


    public static String datePath()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    public static final String dateTime()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMMdd");
    }

    public static Date parseDate(Object str)
    {
        if (str == null)
        {
            return null;
        }
        try
        {
            return parseDate(str.toString(), parsePatterns);
        }
        catch (ParseException e)
        {
            return null;
        }
    }

    public static Date getServerStartDate()
    {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    public static String timeDistance(Date endDate, Date startTime)
    {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        long diff = endDate.getTime() - startTime.getTime();
        long day = diff / nd;
        long hour = diff % nd / nh;
        long min = diff % nd % nh / nm;
        return day + "天" + hour + "小时" + min + "分钟";
    }

    public static Date toDate(LocalDateTime temporalAccessor)
    {
        ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }


    public static Date toDate(LocalDate temporalAccessor)
    {
        LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }

    public static Date lessHour(Date date){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.HOUR_OF_DAY, -1);
        return c.getTime();
    }

    public static Date lessDay(Date date, int len){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DAY_OF_MONTH, len);
        return c.getTime();
    }

    public static Date lessMonth(Date date, int len){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MONTH, -len);
        return c.getTime();
    }

    public static Date lessHourTo(Date date, int len){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.HOUR_OF_DAY, -len);
        return c.getTime();
    }

    public static Date getNowHourTime(){
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH),
                calendar.get(Calendar.HOUR_OF_DAY), 0, 0);
        return calendar.getTime();
    }

    @InitBinder
    public static void initBinder(WebDataBinder binder) {
        // Date 类型转换
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                try {
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                    setValue(dateFormat.parse(text));
                } catch (ParseException e) {
                    throw new IllegalArgumentException("Invalid date format");
                }
            }

            @Override
            public String getAsText() {
                Date value = (Date) getValue();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                return dateFormat.format(value);
            }
        });
    }

}
